package core;

import java.util.Random;

import javax.swing.JOptionPane;

public class Environment {
	public enum Type {
		STATIC, DYNAMIC1, DYNAMIC2, DYNAMIC3
	}

	public AbstractAgent agent;
	public Action.Type current_action;
	public Type type;
	public Floor floor;
	public int k_steps;
	public int steps_count;
	int count = 0;

	public Environment(AbstractAgent agent, Environment.Type dynType, int kSteps) {
		this.floor = new Floor();
		if (this.floor.rooms[agent.x].squares[agent.y].type != Square.Type.Clean) {
			do {
				Random random = new Random();
				agent.y = Math.abs(random.nextInt()) % 8;
			} while (this.floor.rooms[agent.x].squares[agent.y].type == Square.Type.Clean);
		}
		this.agent = agent;
		this.type = dynType;
		this.k_steps = kSteps;
		this.steps_count = kSteps;
	}

	public Perception getPerceptions() {
		/* create a perception with a floor of unknown state */
		Perception perception = new Perception(this.floor);
		/* then add informations according to the agent visibility */

		/* add informations about all the squares */
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 8; j++)
				perception.floor.set(i, j, floor.get(i, j));
		return perception;
	}

	public void update() {
		agent.perceives(getPerceptions());
		agent.update();

		getAction(agent.action());
		System.out.println("Action received: " + current_action);

		if (type == Environment.Type.DYNAMIC1) {
			System.out.println("k step: " + steps_count + " renata step: "
					+ k_steps);
			if (this.steps_count == 0) {
				agent.something_has_changed = this.floor.dynamic1();
				this.steps_count = this.k_steps;
				this.agent.max_steps_per_goal = this.steps_count;
				System.out.println(agent.goals.toString());

			} else {
				this.steps_count--;
				this.agent.max_steps_per_goal = this.steps_count;
			}
		} else if (type == Environment.Type.DYNAMIC2) {
			if (this.steps_count == 0) {
				agent.something_has_changed = this.floor.dynamic2();
				this.steps_count = this.k_steps;
				this.agent.max_steps_per_goal = this.steps_count;

			} else {
				this.steps_count--;
				this.agent.max_steps_per_goal = this.steps_count;
			}
		} else if (type == Environment.Type.DYNAMIC3) {
			if (this.steps_count == 0) {
				agent.something_has_changed = this.floor.dynamic3();
				this.steps_count = this.k_steps;
				this.agent.max_steps_per_goal = this.steps_count;
			} else {
				this.steps_count--;
				this.agent.max_steps_per_goal = this.steps_count;
			}
		}

		if (current_action == Action.Type.DO) {
			if (floor.get(agent.x, agent.y) != Square.Type.Clean)
				count++;

			JOptionPane.showMessageDialog(null, floor.get(agent.x, agent.y)
					+ " reached!");

			if (count == 2 || count == 3 || count == 5) {
				floor.set(agent.x, agent.y, Square.Type.Clean);

				if (count == 2)
					floor.there_s_smoking = false;
				else if (count == 5) {
					floor.there_s_flowers = false;
				}
			}

			// System.out.println("MY CELL BEFORE: " + agent.x + "," + agent.y
			// + ": " + floor.get(agent.x, agent.y));

		}
		if (current_action == Action.Type.NORTH && agent.x - 1 >= 0
				&& floor.isDoor(agent.x - 1, agent.y))
			agent.x--;
		if (current_action == Action.Type.SOUTH && agent.x + 1 < 4
				&& floor.isDoor(agent.x, agent.y))
			agent.x++;
		if (current_action == Action.Type.EAST && agent.y + 1 < 8)
			agent.y++;
		if (current_action == Action.Type.WEST && agent.y - 1 >= 0)
			agent.y--;
	}

	public void getAction(Action.Type action) {
		current_action = action;
	}

	public int performanceMeasure() {
		return this.agent.renata_time / (this.agent.goals.size() + 1);
	}

	public String toString() {
		// StringBuffer sb = new StringBuffer();
		// for (int i = 0; i < 8; i++) {
		// for (int j = 0; j < 8; j++)
		// if (i % 2 == 0) {
		// if (agent.x == i / 2 && agent.y == j)
		// sb.append("[[=]] ");
		// else if (floor.get(i / 2, j) == Square.Type.Flowers)
		// sb.append("FFFFF ");
		// else if (floor.get(i / 2, j) == Square.Type.Meal)
		// sb.append("MMMMM ");
		// else if (floor.get(i / 2, j) == Square.Type.Smoking)
		// sb.append("SSSSS ");
		// else if (floor.get(i / 2, j) == Square.Type.Table)
		// sb.append("TTTTT ");
		// else
		// sb.append("----- ");
		// } else {
		// int tmp = i / 2 - 1 / 2;
		// if (tmp == 3 && floor.isDoor(tmp, j))
		// sb.append("OOOOO ");
		// else if (floor.isDoor(tmp, j))
		// sb.append("@@@@@ ");
		// else
		// sb.append("##### ");
		// }
		// sb.append("\n");
		// }
		// return sb.toString();
		return "";
	}

	public void show() {
		System.out.println(this);
	}
}